/*
     Copyright (C) 2011 Benny Mackney

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef BOX_H
#define BOX_H
/// The number of modes the Box will store
#define BSC_BOX_NUMBEROFMODES 2

#include "bennysc.h"
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <string>
#include <iostream>

class Box
{
    public:
        //! Default constructor
        /*!
            Default constructor that will create a box with default values.
            \sa ~Box()
        */
        Box();
        //! Destructor
        /*!
            Checks the modes to see if the sprite should be freed.
            \sa Box(),set_mode(),get_mode()
        */
        virtual ~Box();

        //! Draw the Box
        /*!
            Draws the box onto the passed screen with offsetting for 2D camera movement. If a sprite exists, will draw that according to boxRect's x and y elements with clipRect as a clipping mask. If no sprite, will fill the rectangle boxRect with boxColour.
            \param screen an SDL_Surface to draw onto (usually the screen, but could be any surface)
            \param camera an SDL_Rect that represents the camera view where the x and y elements are the camera's position in the 2D world. w and h currently unused (possibly for zoom/scaling in the future)
            \sa set_mode(),get_mode(), boxRect, clipRect, sprite, set_x(), set_y(), set_pos(), set_w(), set_h(), set_dimensions(), set_colour(int r, int g, int b), set_colour(SDL_Colour colour), load_sprite(const char* path), set_sprite(SDL_Surface* newSprite
        */
        void draw_object(SDL_Surface* screen,SDL_Rect camera);
        //! Empty tick funtion
        /*!
            Tick function that immediately returns. Allows static, boring boxes like this class to be thrown through the same algorithms as derived classes (players, particles, etc.) without causing issues. Rather useless but there for flexibility.
        */
        virtual void tick();
        //! Rectangular collision detection with other Box objects/derivatives
        /*!
            Returns true if the Box collides with (overlaps) the collider
            \param collider a pointer to a Box or derived class that will be tested for collision with this Box
            \sa collides(const SDL_Rect* collider)
        */
        bool collides(const Box* collider) const;
        //! Rectangular collision detection with SDL_Rects and derivatives
        /*!
            Returns true if the Box collides with (overlaps) the collider
            \param collider a pointer to an SDL_Rect or derived class that will be tested for collision with this Box
            \sa collides(const Box* collider)
        */
        bool collides(const SDL_Rect* collider) const;
        //! Gets the x position of the Box
        /*! This is the absolute position, does not account for centered drawing
            \sa get_y(), get_x1(), get_x2(), get_y1(), get_y2()
        */
        Sint16 get_x() const;
        //! Gets the y position of the Box
        /*! This is the absolute position, does not account for centered drawing
            \sa get_x(), get_x1(), get_x2(), get_y1(), get_y2()
        */
        Sint16 get_y() const;
        //! Gets the minimum x position of the Box
        /*! This accounts for centered drawing
            \sa get_x(), get_y(), get_x2(), get_y1(), get_y2()
        */
        Sint16 get_x1() const;
        //! Gets the minimum y position of the Box
        /*! This accounts for centered drawing
            \sa get_x(), get_y(), get_x1(), get_x2(), get_y2()
        */
        Sint16 get_y1() const;
        //! Gets the maximum x position of the Box
        /*! This accounts for centered drawing
            \sa get_x(), get_y(), get_x1(), get_y1(), get_y2()
        */
        Sint16 get_x2() const;
        //! Gets the maximum y position of the Box
        /*! This accounts for centered drawing
            \sa get_x(), get_y(), get_x1(), get_x2(), get_y1()
        */
        Sint16 get_y2() const;
        //! Sets the x position of the Box
        void set_x(Sint16 x);
        //! Sets the y position of the Box
        void set_y(Sint16 y);
        //! Sets the x and y positions of the Box
        void set_pos(const Sint16 x, const Sint16 y);
        //! Sets the width of the Box
        void set_w(Uint16 w);
        //! Sets the height of the Box
        void set_h(Uint16 h);
        //! Sets the width and height of the Box
        void set_dimensions(Uint16 w,Uint16 h);
        SDL_Rect get_dimensions();
        SDL_Rect get_position();
        //! Loads a sprite and sets it to be used
        /*! \param path a C string that is a filename to load*/
        int load_sprite(const char* path);
        //! Sets a sprite to be used
        /*! It's usually recommended that you use Box's "free sprite on destruction" mode if this sprite is going to be shared. Not using this mode may result in serious errors if this Box is destroyed before other objects using the sprite
        \param newSprite Pointer to the SDL_Surface to be used*/
        int set_sprite(SDL_Surface* newSprite);
        SDL_Colour boxColour;

        //! Sets a mode of the Box
        /*!
            \param mode An integer that represents the mode to be set
            \param val Boolean state of the mode
            \sa get_mode(), bennysc.h
        */
        void set_mode(int mode, bool val);
        //! Gets the state of a mode of the Box
        /*!
            \param mode An integer that represents the mode to be get'd
            \sa set_mode(), bennysc.h
        */
        bool get_mode(int mode) const;

        //! Set box colour
        /*!
            Sets the box's colour for non-sprite mode.
            \param r amount of red colour
            \param g amount of green colour
            \param b amount of blue colour
            \sa set_colour(SDL_Colour colour)
        */
        void set_colour(int r, int g, int b);

        //! Set box colour
        /*!
            Sets the box's colour for non-sprite mode.
            \param colour Colour as an SDL_Colour
            \sa set_colour(int r, int b, int g)
        */
        void set_colour(SDL_Colour colour);


        SDL_Rect boxRect;
        SDL_Rect clipRect;
        SDL_Surface* sprite;

    protected:
    private:
        bool modes[BSC_BOX_NUMBEROFMODES];
};

#endif // BOX_H
